dojo.provide("uws.Data");
dojo.require("dojox.data.AndOrWriteStore");

var dataStore = null;
var root = null;

function prepareDataStore(){
	/*
		from http://www.dojotoolkit.org/forum/dojo-core-dojo-0-9/dojo-core-support/json-export-hierarchical-instead-referenced-items
		
		This  function makes the json that the data store exports to be the same as the file format it reads
	*/
	dojo.extend(dojox.data.AndOrWriteStore, {
		_flatten: function (/* anything */value,/* boolean */avoidReferencing) {
			if (this.isItem(value)) {
				var item = value;
				if (avoidReferencing) {
					return this._getSerializableItem(item, avoidReferencing);
				} else {
					// Given an item, return an serializable object that provides a
					// reference to the item.
					// For example, given kermit:
					// var kermit = store.newItem({id:2, name:"Kermit"});
					// we want to return
					// {_reference:2}
					var identity = this.getIdentity(item);
					var referenceObject = {
						_reference: identity
					};
					return referenceObject;
				}
			} else {
				if (typeof value === "object") {
					for (var type in this._datatypeMap) {
						var typeMap = this._datatypeMap[type];
						if (dojo.isObject(typeMap) && !dojo.isFunction(typeMap)) {
							if (value instanceof typeMap.type) {
								if (!typeMap.serialize) {
									throw new Error("ItemFileWriteStore: No serializer defined for type mapping: [" + type + "]");
								}
								return {
									_type: type,
									_value: typeMap.serialize(value)
								};
							}
						} else if (value instanceof typeMap) {
							//SImple mapping, therefore, return as a toString serialization.
							return {
								_type: type,
								_value: value.toString()
							};
						}
					}
				}
				return value;
			}
		},
		
		_getNewFileContentString: function (/* boolean */avoidReferencing) {
			// summary:
			// Generate a string that can be saved to a file.
			// The result should look similar to:
			// http://trac.dojotoolkit.org/browser/dojo/trunk/tests/data/countries.json
			var serializableStructure = {};
			
			var identifierAttribute = this._getIdentifierAttribute();
			if (identifierAttribute !== Number) {
				serializableStructure.identifier = identifierAttribute;
			}
			if (this._labelAttr) {
				serializableStructure.label = this._labelAttr;
			}
			serializableStructure.items = this._getSerializableItems(avoidReferencing ? this._arrayOfTopLevelItems : this._arrayOfAllItems, avoidReferencing);
			var prettyPrint = true;
			return ((dojo.isIE) ? dojo.toJson(serializableStructure, prettyPrint).replace(/,[\s]+undefined/g, "") : dojo.toJson(serializableStructure, prettyPrint));
		},
		_getSerializableItems: function (/* Array */items,/* boolean */avoidReferencing) {
			var serializableItems = [];
			for (var i = 0; i < items.length; ++i) {
				var item = items[i];
				if (item !== null) {
					var serializableItem = this._getSerializableItem(item, avoidReferencing);
					serializableItems.push(serializableItem);
				}
			}
			return serializableItems;
		},
		_getSerializableItem: function (/* item */item,	/* boolean */avoidReferencing) {
			var serializableItem = {};
			for (var key in item) {
				if (key !== this._storeRefPropName && key !== this._itemNumPropName && key !== this._reverseRefMap && key !== this._rootItemPropName) {
					var attribute = key;
					var valueArray = this.getValues(item, attribute);
					if (valueArray.length == 1) {
						serializableItem[attribute] = this._flatten(valueArray[0], avoidReferencing);
					} else {
						var serializableArray = [];
						for (var j = 0; j < valueArray.length; ++j) {
							serializableArray.push(this._flatten(valueArray[j], avoidReferencing));
							serializableItem[attribute] = serializableArray;
						}
					}
				}
			}
			return serializableItem;
		}
	});
}

function initDataStore(dataURL){
	//instantiate
	dataStore = new dojox.data.AndOrWriteStore({
        url: dataURL
    });
	
	//overide the empty function to save the file, ajax style
	dataStore._saveEverything = function(completeCallback,errorCallback,newFileContentString){
		newFileContentString = dataStore._getNewFileContentString(true);	//avoid_referrencing: true
		
		dojo.xhrPost({
			url:"ajax/saveDataStore.php",
			postData:"data="+newFileContentString,
			load:function(response, ioArgs){
				dataStore.fetchItemByIdentity({
					identity: 'project',
					scope: this,
					onItem:function(item){
						setTimeout(function(){
							if(dataStore.getValue(item, "db_key") != parseInt(response)){
								dataStore.setValue(item, "db_key", response);
								dataStore.save();
							}
							writeToStatusBar("Saved", 5000);
						}, 10);
					}
				});
				completeCallback();
			},
			error:function(error,ioArgs){
				writeToStatusBar(error, 5000);
				errorCallback();
			}
		});
		
	}
}

function openProject(projectId){
	writeToStatusBar("Loading project...");
	
	if(dijit.byId('viewProjects')){
		dijit.byId("tabContainer").removeChild(dijit.byId('viewProjects'));
		dijit.byId('viewProjects').destroyRecursive(true);
	}
	
	//restore datastore
	if(dataStore!=null && dataStore.isDirty()){
		if(tree!=null) tree.destroyRecursive();
		closeProject();
	}else if(dataStore!=null){
		closeProject();
	}
	
	initDataStore("ajax/openDataStore.php?id=" + projectId);
	prepareDataStore();	
	buildNavTree();
	
	dojo.subscribe("tabContainer-selectChild", function(child){
		document.title=child.title+" - "+username+" - UML WebStudio";
		surfaceManager.setVisibleSurface(child.id);
	});
	
	dojo.subscribe("tabContainer-removeChild", function(child){
		surfaceManager.removeItem(child.id, true, false);
	});
}

